#include "path_iterator.h"
#include "path.h"

PathIterator::PathIterator(Path& path,unsigned int step,bool loop)
	: path(path){
	this->initial=path.begin();
	this->last=++path.begin();

	this->step=step;
	this->_loop=loop;

	this->count=0;
	this->newStep=0;

	this->_end=false;
	this->_begin=false;
}

PathIterator::~PathIterator(){

}

Point PathIterator::getCurrent()const{
	return this->current;
}

PathData PathIterator::getInitial()const{
	return *this->initial;
}

PathData PathIterator::getLast()const{
	return *this->last;
}

void PathIterator::setNewStep(unsigned int delta_step){
	int w = this->newStep;
	if(this->newStep==0)
		w = this->step+delta_step;
	else
		w += delta_step;

	if(w<=0)
		this->newStep=1;
	else
		this->newStep=w;
}

void PathIterator::updateFollowers(){
	for(std::list<IFollower*>::iterator it=followers.begin();it!=followers.end();++it){
		if(!end()){
			Point dir = initial->p-last->p;
			(*it)->updatePosition(current,dir,initial->info);
		}else if(end()){
			(*it)->updatePosition(current,Point(0,0,0),initial->info);
		}
	}
}

void PathIterator::addFollower(IFollower* follower){
	this->followers.push_back(follower);
}

void PathIterator::removeFollower(IFollower* follower){
	this->followers.remove(follower);
}

PathIterator& PathIterator::operator ++(){
	if(end())
		return *this;

	++this->count;
	if(this->count>=this->step || begin()){
		if(this->newStep!=0){
			this->step = this->newStep;
			this->newStep = 0;
		}

		++initial;
		++last;

		if(last==path.end() && loop()){
			last=path.begin();
		}

		if(initial==path.end() && loop()){
			initial=path.begin();
		}

		if(!begin())
			count=0;
		else
			_begin=false;

	}
	_end   = (last==path.end());

	if(!end()){
		current = ((( (Point)(*last)-(Point)(*initial))*(1/(float)step))*(float)count)+(Point)(*initial);
	}

	updateFollowers();

	return *this;
}

PathIterator& PathIterator::operator --(){
	if(begin())
		return *this;

	++this->count;
	if(this->count>=this->step || end()){
		if(this->newStep!=0){
			this->step = this->newStep;
			this->newStep = 0;
		}

		--initial;
		--last;

		if(initial==path.end() && loop()){
			initial=path.begin();
		}

		if(last==path.end() && loop()){
			last=path.begin();
		}

		if(!end())
			count=0;
		else
			_end=false;

	}
	_begin   = (initial==path.end());

	if(!begin()){
		current = ((( (Point)(*initial)-(Point)(*last))*(1/(float)step))*(float)count)+(Point)(*last);
	}

	updateFollowers();

	return *this;
}
